﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenSource.UPnP;
using System.IO;
using System.Collections;
using System.Reflection;
using System.Threading;

namespace ApplicationClienteCommunicante
{
    class ClientApplicationCommunicante
    {

        private UPnPDevice root;
        private UPnPService list;
        private int nb_dev;
        private UPnPSmartControlPoint cp;

        UPnPArgument[] args2 = new UPnPArgument[3];
        UPnPArgument[] args3 = new UPnPArgument[0];
        private UPnPSmartControlPoint cp2;

        ArrayList tabparametre = new ArrayList();

        MainWindow mainwindow;
        string ResultatFinal = "AA";

        static ArrayList _zones = new ArrayList();

        static public ArrayList Zones
        {
            get { return _zones; }
            set { _zones = value; }
        }

        public ClientApplicationCommunicante(MainWindow mainw)
        {
            nb_dev = 0;
            mainwindow = mainw; 

            root = UPnPDevice.CreateRootDevice(360, 1.0, "");
            root.FriendlyName = "ApplicationCommunicante1";
            root.DeviceURN = "urn:schemas-upnp-org:device:ApplicationCommunicante1:1";
            root.HasPresentation = false;
            root.Manufacturer = "sbai";
            root.ModelName = "UPnP sample for kids";
            root.UniqueDeviceName = "12345678-153f-430d-82f3-dff320c17708";

            list = new UPnPService(1.0, "Sample", "urn:schemas-upnp-org:service:Sample:1", true, this);

            list.AddMethod("loadParametreInterface");
            list.AddMethod("getResultatFinal");
            root.AddService(list);
            root.Advertise();

        }

      

        public void Search()
        {
            Console.WriteLine("/////////////////////////////////////////////////////////////////");

            Console.WriteLine("Nom du dispooooooooo est : " + MainWindow.nomdispo);
            Console.WriteLine("/////////////////////////////////////////////////////////////////");

            cp = new UPnPSmartControlPoint(new UPnPSmartControlPoint.DeviceHandler(NewDevice));
            cp.OnRemovedDevice += new UPnPSmartControlPoint.DeviceHandler(DeviceQuit);
            cp.Rescan();
        }


        /**
        * \NewDevice                pour la recherche d'un device sur le réseau.
         * \param    sender1        sender1 pour le sender qui a declencher la methode.
        * \param    device          device est le device qui va apparaitre sur réseau.
         */
        public void NewDevice(UPnPSmartControlPoint sender, UPnPDevice device)
        {


            if (device.FriendlyName != MainWindow.nomdispo)
            {
                Console.WriteLine("ignoring " + device.FriendlyName);
                return;
            }

            nb_dev++;
            _zones.Add(nb_dev);

            Console.WriteLine(MainWindow.nomdispo + " found: " + nb_dev);
           }

        /**
        * \DeviceQuit               affiche un message si un device a quitté le réseau
        * \param    sender1         sender1 pour le sender qui a déclenché la méthode.
        * \param    device          device est le device qui va quitter le réseau.
        */

        public void DeviceQuit(UPnPSmartControlPoint sender, UPnPDevice device)
        {

            Console.Out.WriteLine(MainWindow.nomdispo + " quit: " + nb_dev);

            nb_dev--;
        }

        public void getParametreInterface(int width, int height) {


            Console.WriteLine("w= " +width);
            Console.WriteLine("H= " + height);

            args2[0] = new UPnPArgument("name", "ApplicationCommunicante1");
            args2[1] = new UPnPArgument("width", width);
            args2[2] = new UPnPArgument("height", height);

            cp2 = new UPnPSmartControlPoint(new UPnPSmartControlPoint.DeviceHandler(sendParametreInterface));
        
        }

        public void sendParametreInterface(UPnPSmartControlPoint sender, UPnPDevice device) {

            if (device.FriendlyName == MainWindow.nomdispo)
            {
                
                UPnPService serv = device.GetService("Sample");

                if (serv == null)
                {
                    Console.Error.WriteLine("Could not find service `Sample' in device ");
                }

               

                string retval;

 
                try
                {
                    retval=(string)serv.InvokeSync("recupereParametreInterface", args2);
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine(e);
                    retval = "ERROR";
                }

                //Console.WriteLine("la valeur de retval est " + retval);


                if (retval != null)
                {

                    Console.WriteLine("valeuuuuuuuuuuuuuuurrrrrrrrrrrrrrrrr de retval est : " + retval);
                    
                }

                mainwindow.RefreshMessage2(retval);

              
            }

        
        
        }

        public void finsentDecision()
        {

            cp2 = new UPnPSmartControlPoint(new UPnPSmartControlPoint.DeviceHandler(finsentDecisionFinale));
        
        }

        public void finsentDecisionFinale(UPnPSmartControlPoint sender, UPnPDevice device)
        {

            if (device.FriendlyName == MainWindow.nomdispo)
            {
                Console.WriteLine("trueeeeeeeeeeeeeeeee");

                UPnPService serv = device.GetService("Sample");

                if (serv == null)
                {
                    Console.Error.WriteLine("Could not find service `Sample' in device ");
                }

                Console.WriteLine("service  Sample2 is Found");

                UPnPArgument[] args3 = new UPnPArgument[1];

                string decisionFinale = mainwindow.DecisionFinale;

                while (decisionFinale == "")
                {
                    Console.WriteLine("sleeeeeeeeeeeeeeeeeeppp");
                    decisionFinale = mainwindow.DecisionFinale;
                }
                Console.WriteLine(decisionFinale);
                args3[0] = new UPnPArgument("decisionFinale", decisionFinale);

                serv.InvokeSync("updateresultatFinal", args3);

           
            }

        
        
        
        }

        /**
          * \startUPnP       pour démarrer le device

          */
        public void startUPnP()
        {
            root.StartDevice();
            Console.WriteLine("Serveur start");
        }

        /**
        * \stopUPnP       pour arrêter le device
        */
        public void stopUPnP()
        {
            root.StopDevice();
            Console.WriteLine("Serveur stopped");

        }


        /**
        * \loadFile       pour télécharger le fichier de description
        * \param         InFile est le fichier de descrption passé sous forme d'une chaîne de caractères
        */
        public void loadParametreInterface(double width, double height)
        {
            Console.WriteLine("le width est : " + height);
            Console.WriteLine("le height: " + width);

            tabparametre.Add(width);
            tabparametre.Add(height);

        }

        public ArrayList gettabparametre() {

            return tabparametre;
        }




        public void getResultatFinal(string resultat)
        {
          
            Console.WriteLine("methode getResultatFinal est invoquée");
            Console.WriteLine(resultat);

            ResultatFinal = resultat;
        }

        public string postResultatFinal() {

            while (ResultatFinal=="AA")
            {
            Thread.SpinWait(1000000);
           }
            return ResultatFinal;
        }
    
    }
}
